home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / ibus / setup / main.py < prev    next >
Text File  |  2009-11-05  |  17KB  |  416 lines

  1. # vim:set et sts=4 sw=4:
  2. #
  3. # ibus - The Input Bus
  4. #
  5. # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
  6. #
  7. # This library is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU Lesser General Public
  9. # License as published by the Free Software Foundation; either
  10. # version 2 of the License, or (at your option) any later version.
  11. #
  12. # This library is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU Lesser General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public
  18. # License along with this program; if not, write to the
  19. # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20. # Boston, MA  02111-1307  USA
  21.  
  22. import gettext
  23. import os
  24. import signal
  25. import sys
  26. import time
  27. import gtk
  28. import gobject
  29. import pango
  30. import ibus
  31. import keyboardshortcut
  32. from os import path
  33. from xdg import BaseDirectory
  34. from gtk import gdk
  35. from gtk import glade
  36. from enginecombobox import EngineComboBox
  37. from enginetreeview import EngineTreeView
  38. from engineabout import EngineAbout
  39.  
  40. _  = lambda a : gettext.dgettext("ibus", a)
  41. N_ = lambda a : a
  42.  
  43. (
  44.     COLUMN_NAME,
  45.     COLUMN_ENABLE,
  46.     COLUMN_PRELOAD,
  47.     COLUMN_VISIBLE,
  48.     COLUMN_ICON,
  49.     COLUMN_DATA,
  50. ) = range(6)
  51.  
  52. (
  53.     DATA_NAME,
  54.     DATA_LOCAL_NAME,
  55.     DATA_LANG,
  56.     DATA_ICON,
  57.     DATA_AUTHOR,
  58.     DATA_CREDITS,
  59.     DATA_EXEC,
  60.     DATA_STARTED,
  61.     DATA_PRELOAD
  62. ) = range(9)
  63.  
  64. class Setup(object):
  65.     def __flush_gtk_events(self):
  66.         while gtk.events_pending():
  67.             gtk.main_iteration()
  68.  
  69.     def __init__(self):
  70.         super(Setup, self).__init__()
  71.         localedir = os.getenv("IBUS_LOCALEDIR")
  72.         gettext.bindtextdomain("ibus", localedir)
  73.         glade.bindtextdomain("ibus", localedir)
  74.         gettext.bind_textdomain_codeset("ibus", "UTF-8")
  75.         glade.textdomain("ibus")
  76.         glade_file = path.join(path.dirname(__file__), "./setup.glade")
  77.         self.__xml = glade.XML(glade_file)
  78.         self.__bus = None
  79.         self.__init_bus()
  80.         self.__init_ui()
  81.  
  82.     def __init_ui(self):
  83.         # add icon search path
  84.         self.__window = self.__xml.get_widget("window_preferences")
  85.         self.__window.connect("delete-event", gtk.main_quit)
  86.  
  87.         self.__button_close = self.__xml.get_widget("button_close")
  88.         self.__button_close.connect("clicked", gtk.main_quit)
  89.  
  90.         # auto start ibus
  91.         self.__checkbutton_auto_start = self.__xml.get_widget("checkbutton_auto_start")
  92.         self.__checkbutton_auto_start.set_active(self.__is_auto_start())
  93.         self.__checkbutton_auto_start.connect("toggled", self.__checkbutton_auto_start_toggled_cb)
  94.  
  95.         # keyboard shortcut
  96.         # trigger
  97.         self.__config = self.__bus.get_config()
  98.         shortcuts = self.__config.get_value(
  99.                         "general/hotkey", "trigger",
  100.                         ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT)
  101.  
  102.         button = self.__xml.get_widget("button_trigger")
  103.         entry = self.__xml.get_widget("entry_trigger")
  104.         text = "; ".join(shortcuts)
  105.         entry.set_text(text)
  106.         entry.set_tooltip_text(text)
  107.         button.connect("clicked", self.__shortcut_button_clicked_cb,
  108.                     N_("trigger"), "general/hotkey", "trigger", entry)
  109.  
  110.         # next engine
  111.         shortcuts = self.__config.get_value(
  112.                         "general/hotkey", "next_engine",
  113.                         ibus.CONFIG_GENERAL_SHORTCUT_NEXT_ENGINE_DEFAULT)
  114.         button = self.__xml.get_widget("button_next_engine")
  115.         entry = self.__xml.get_widget("entry_next_engine")
  116.         text = "; ".join(shortcuts)
  117.         entry.set_text(text)
  118.         entry.set_tooltip_text(text)
  119.         button.connect("clicked", self.__shortcut_button_clicked_cb,
  120.                     N_("next input method"), "general/hotkey", "next_engine", entry)
  121.  
  122.         # prev engine
  123.         shortcuts = self.__config.get_value(
  124.                         "general/hotkey", "prev_engine",
  125.                         ibus.CONFIG_GENERAL_SHORTCUT_PREV_ENGINE_DEFAULT)
  126.         button = self.__xml.get_widget("button_prev_engine")
  127.         entry = self.__xml.get_widget("entry_prev_engine")
  128.         text = "; ".join(shortcuts)
  129.         entry.set_text(text)
  130.         entry.set_tooltip_text(text)
  131.         button.connect("clicked", self.__shortcut_button_clicked_cb,
  132.                     N_("previous input method"), "general/hotkey", "prev_engine", entry)
  133.  
  134.         # lookup table orientation
  135.         self.__combobox_lookup_table_orientation = self.__xml.get_widget("combobox_lookup_table_orientation")
  136.         self.__combobox_lookup_table_orientation.set_active(
  137.             self.__config.get_value("panel", "lookup_table_orientation", 0))
  138.         self.__combobox_lookup_table_orientation.connect("changed",
  139.             self.__combobox_lookup_table_orientation_changed_cb)
  140.  
  141.         # auto hide
  142.         self.__combobox_panel_show = self.__xml.get_widget("combobox_panel_show")
  143.         self.__combobox_panel_show.set_active(
  144.             self.__config.get_value("panel", "show", 1))
  145.         self.__combobox_panel_show.connect("changed", self.__combobox_panel_show_changed_cb)
  146.  
  147.         # custom font
  148.         self.__checkbutton_custom_font = self.__xml.get_widget("checkbutton_custom_font")
  149.         self.__checkbutton_custom_font.set_active(
  150.             self.__config.get_value("panel", "use_custom_font", False))
  151.         self.__checkbutton_custom_font.connect("toggled", self.__checkbutton_custom_font_toggled_cb)
  152.  
  153.         self.__label_custom_font = self.__xml.get_widget("label_custom_font")
  154.         self.__fontbutton_custom_font = self.__xml.get_widget("fontbutton_custom_font")
  155.         if self.__config.get_value("panel", "use_custom_font", False):
  156.             self.__label_custom_font.set_sensitive(True)
  157.             self.__fontbutton_custom_font.set_sensitive(True)
  158.         else:
  159.             self.__label_custom_font.set_sensitive(False)
  160.             self.__fontbutton_custom_font.set_sensitive(False)
  161.         font_name = gtk.settings_get_default().get_property("gtk-font-name")
  162.         font_name = unicode(font_name, "utf-8")
  163.         font_name = self.__config.get_value("panel", "custom_font", font_name)
  164.         self.__fontbutton_custom_font.connect("notify::font-name", self.__fontbutton_custom_font_notify_cb)
  165.         self.__fontbutton_custom_font.set_font_name(font_name)
  166.  
  167.         # show ime name
  168.         self.__checkbutton_show_im_name = self.__xml.get_widget("checkbutton_show_im_name")
  169.         self.__checkbutton_show_im_name.set_active(
  170.             self.__config.get_value("panel", "show_im_name", False))
  171.         self.__checkbutton_show_im_name.connect("toggled", self.__checkbutton_show_im_name_toggled_cb)
  172.  
  173.         # use system keyboard layout setting
  174.         self.__checkbutton_use_sys_layout = self.__xml.get_widget("checkbutton_use_sys_layout")
  175.         self.__checkbutton_use_sys_layout.set_active(
  176.             self.__config.get_value("general", "use_system_keyboard_layout", False))
  177.         self.__checkbutton_use_sys_layout.connect("toggled", self.__checkbutton_use_sys_layout_toggled_cb)
  178.  
  179.         # init engine page
  180.         self.__engines = self.__bus.list_engines()
  181.         self.__combobox = EngineComboBox(self.__engines)
  182.         self.__combobox.show()
  183.         self.__xml.get_widget("alignment_engine_combobox").add(self.__combobox)
  184.  
  185.         tmp_dict = {}
  186.         for e in self.__engines:
  187.             tmp_dict[e.name] = e
  188.         engine_names = self.__config.get_value("general", "preload_engines", [])
  189.         engines = []
  190.         for n in engine_names:
  191.             if n in tmp_dict:
  192.                 engines.append(tmp_dict[n])
  193.         self.__treeview = EngineTreeView(engines)
  194.         self.__treeview.show()
  195.         self.__xml.get_widget("scrolledwindow_engine_treeview").add(self.__treeview)
  196.  
  197.         self.__treeview.connect("changed", self.__treeview_changed_cb)
  198.  
  199.         button = self.__xml.get_widget("button_engine_add")
  200.         button.connect("clicked",
  201.                        lambda *args:self.__treeview.append_engine(self.__combobox.get_active_engine()))
  202.         button = self.__xml.get_widget("button_engine_remove")
  203.         button.connect("clicked", lambda *args:self.__treeview.remove_engine())
  204.         button = self.__xml.get_widget("button_engine_up")
  205.         button.connect("clicked", lambda *args:self.__treeview.move_up_engine())
  206.  
  207.         button = self.__xml.get_widget("button_engine_down")
  208.         button.connect("clicked", lambda *args:self.__treeview.move_down_engine())
  209.  
  210.         button = self.__xml.get_widget("button_engine_about")
  211.         button.connect("clicked", self.__button_engine_about_cb)
  212.  
  213.     def __button_engine_about_cb(self, button):
  214.         engine = self.__treeview.get_select_engine()
  215.         if engine:
  216.             about = EngineAbout(engine)
  217.             about.run()
  218.             about.destroy()
  219.  
  220.     def __treeview_changed_cb(self, treeview):
  221.         engines = self.__treeview.get_engines()
  222.         engine_names = map(lambda e: e.name, engines)
  223.         self.__config.set_list("general", "preload_engines", engine_names, "s")
  224.  
  225.     def __init_bus(self):
  226.         try:
  227.             self.__bus = ibus.Bus()
  228.             # self.__bus.connect("config-value-changed", self.__config_value_changed_cb)
  229.             # self.__bus.connect("config-reloaded", self.__config_reloaded_cb)
  230.             # self.__bus.config_add_watch("/general")
  231.             # self.__bus.config_add_watch("/general/hotkey")
  232.             # self.__bus.config_add_watch("/panel")
  233.         except:
  234.             while self.__bus == None:
  235.                 message = _("IBus daemon is not started. Do you want to start it now?")
  236.                 dlg = gtk.MessageDialog(type = gtk.MESSAGE_QUESTION,
  237.                         buttons = gtk.BUTTONS_YES_NO,
  238.                         message_format = message)
  239.                 id = dlg.run()
  240.                 dlg.destroy()
  241.                 self.__flush_gtk_events()
  242.                 if id != gtk.RESPONSE_YES:
  243.                     sys.exit(0)
  244.                 pid = os.spawnlp(os.P_NOWAIT, "ibus-daemon", "ibus-daemon")
  245.                 time.sleep(1)
  246.                 try:
  247.                     self.__bus = ibus.Bus()
  248.                 except:
  249.                     continue
  250.                 message = _("IBus has been started! "
  251.                     "If you can not use IBus, please add below lines in $HOME/.bashrc, and relogin your desktop.\n"
  252.                     "  export GTK_IM_MODULE=ibus\n"
  253.                     "  export XMODIFIERS=@im=ibus\n"
  254.                     "  export QT_IM_MODULE=ibus"
  255.                     )
  256.                 dlg = gtk.MessageDialog(type = gtk.MESSAGE_INFO,
  257.                                         buttons = gtk.BUTTONS_OK,
  258.                                         message_format = message)
  259.                 id = dlg.run()
  260.                 dlg.destroy()
  261.                 self.__flush_gtk_events()
  262.  
  263.     def __shortcut_button_clicked_cb(self, button, name, section, _name, entry):
  264.         buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)
  265.         title = _("Select keyboard shortcut for %s") %  _(name)
  266.         dialog = keyboardshortcut.KeyboardShortcutSelectionDialog(buttons = buttons, title = title)
  267.         text = entry.get_text()
  268.         if text:
  269.             shortcuts = text.split("; ")
  270.         else:
  271.             shortcuts = None
  272.         dialog.set_shortcuts(shortcuts)
  273.         id = dialog.run()
  274.         shortcuts = dialog.get_shortcuts()
  275.         dialog.destroy()
  276.         if id != gtk.RESPONSE_OK:
  277.             return
  278.         self.__config.set_list(section, _name, shortcuts, "s")
  279.         text = "; ".join(shortcuts)
  280.         entry.set_text(text)
  281.         entry.set_tooltip_text(text)
  282.  
  283.  
  284.     def __item_started_column_toggled_cb(self, cell, path_str, model):
  285.  
  286.         # get toggled iter
  287.         iter = model.get_iter_from_string(path_str)
  288.         data = model.get_value(iter, COLUMN_DATA)
  289.  
  290.         # do something with the value
  291.         if data[DATA_STARTED] == False:
  292.             try:
  293.                 self.__bus.register_start_engine(data[DATA_LANG], data[DATA_NAME])
  294.             except Exception, e:
  295.                 dlg = gtk.MessageDialog(type = gtk.MESSAGE_ERROR,
  296.                         buttons = gtk.BUTTONS_CLOSE,
  297.                         message_format = str(e))
  298.                 dlg.run()
  299.                 dlg.destroy()
  300.                 self.__flush_gtk_events()
  301.                 return
  302.         else:
  303.             try:
  304.                 self.__bus.register_stop_engine(data[DATA_LANG], data[DATA_NAME])
  305.             except Exception, e:
  306.                 dlg = gtk.MessageDialog(type = gtk.MESSAGE_ERROR,
  307.                         buttons = gtk.BUTTONS_CLOSE,
  308.                         message_format = str(e))
  309.                 dlg.run()
  310.                 dlg.destroy()
  311.                 self.__flush_gtk_events()
  312.                 return
  313.         data[DATA_STARTED] = not data[DATA_STARTED]
  314.  
  315.         # set new value
  316.         model.set(iter, COLUMN_ENABLE, data[DATA_STARTED])
  317.  
  318.     def __item_preload_column_toggled_cb(self, cell, path_str, model):
  319.  
  320.         # get toggled iter
  321.         iter = model.get_iter_from_string(path_str)
  322.         data = model.get_value(iter, COLUMN_DATA)
  323.  
  324.         data[DATA_PRELOAD] = not data[DATA_PRELOAD]
  325.         engine = "%s:%s" % (data[DATA_LANG], data[DATA_NAME])
  326.  
  327.         if data[DATA_PRELOAD]:
  328.             if engine not in self.__preload_engines:
  329.                 self.__preload_engines.add(engine)
  330.                 self.__config.set_list("general", "preload_engines", list(self.__preload_engines), "s")
  331.         else:
  332.             if engine in self.__preload_engines:
  333.                 self.__preload_engines.remove(engine)
  334.                 self.__config.set_list("general", "preload_engines", list(self.__preload_engines), "s")
  335.  
  336.         # set new value
  337.         model.set(iter, COLUMN_PRELOAD, data[DATA_PRELOAD])
  338.  
  339.     def __is_auto_start(self):
  340.         link_file = path.join(BaseDirectory.xdg_config_home, "autostart/ibus.desktop")
  341.         ibus_desktop = path.join(os.getenv("IBUS_PREFIX"), "share/applications/ibus.desktop")
  342.  
  343.         if not path.exists(link_file):
  344.             return False
  345.         if not path.islink(link_file):
  346.             return False
  347.         if path.realpath(link_file) != ibus_desktop:
  348.             return False
  349.         return True
  350.  
  351.     def __checkbutton_auto_start_toggled_cb(self, button):
  352.         auto_start_dir = path.join(BaseDirectory.xdg_config_home, "autostart")
  353.         if not path.isdir(auto_start_dir):
  354.             os.makedirs(auto_start_dir)
  355.  
  356.         link_file = path.join(BaseDirectory.xdg_config_home, "autostart/ibus.desktop")
  357.         ibus_desktop = path.join(os.getenv("IBUS_PREFIX"), "share/applications/ibus.desktop")
  358.         # unlink file
  359.         try:
  360.             os.unlink(link_file)
  361.         except:
  362.             pass
  363.         if self.__checkbutton_auto_start.get_active():
  364.             os.symlink(ibus_desktop, link_file)
  365.  
  366.     def __combobox_lookup_table_orientation_changed_cb(self, combobox):
  367.         self.__config.set_value(
  368.             "panel", "lookup_table_orientation",
  369.             self.__combobox_lookup_table_orientation.get_active())
  370.  
  371.     def __combobox_panel_show_changed_cb(self, combobox):
  372.         self.__config.set_value(
  373.             "panel", "show",
  374.             self.__combobox_panel_show.get_active())
  375.  
  376.     def __checkbutton_custom_font_toggled_cb(self, button):
  377.         if self.__checkbutton_custom_font.get_active():
  378.             self.__label_custom_font.set_sensitive(True)
  379.             self.__fontbutton_custom_font.set_sensitive(True)
  380.             self.__config.set_value("panel", "use_custom_font", True)
  381.         else:
  382.             self.__label_custom_font.set_sensitive(False)
  383.             self.__fontbutton_custom_font.set_sensitive(False)
  384.             self.__config.set_value("panel", "use_custom_font", False)
  385.  
  386.     def __fontbutton_custom_font_notify_cb(self, button, arg):
  387.         font_name = self.__fontbutton_custom_font.get_font_name()
  388.         font_name = unicode(font_name, "utf-8")
  389.         self.__config.set_value("panel", "custom_font", font_name)
  390.  
  391.     def __checkbutton_show_im_name_toggled_cb(self, button):
  392.         value = self.__checkbutton_show_im_name.get_active()
  393.         self.__config.set_value("panel", "show_im_name", value)
  394.  
  395.     def __checkbutton_use_sys_layout_toggled_cb(self, button):
  396.         value = self.__checkbutton_use_sys_layout.get_active()
  397.         self.__config.set_value("general", "use_system_keyboard_layout", value)
  398.  
  399.     def __config_value_changed_cb(self, bus, section, name, value):
  400.         pass
  401.  
  402.     def __config_reloaded_cb(self, bus):
  403.         pass
  404.  
  405.     def __sigusr1_cb(self, *args):
  406.         self.__window.present()
  407.  
  408.     def run(self):
  409.         self.__window.show_all()
  410.         signal.signal(signal.SIGUSR1, self.__sigusr1_cb)
  411.         gtk.main()
  412.  
  413. if __name__ == "__main__":
  414.     setup = Setup()
  415.     setup.run()
  416.